package cn.pugle.base.thread.ticketlock;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * TicketLock2能不能用ConcurrentHashMap和AtomicInteger进行优化呢:
 * <p>
 * get get 不锁没啥问题, CHM解决了向map中put不冲突的问题, 原子变量解决了自增一可能出的问题.
 * get rm 如果不锁, 会造成 线程1判断decrementAndGet()==0之后线程2getLock(), 然后锁被线程1remove了.
 * rm rm 也没啥问题, 原子变量解决了减一可能出的问题
 *
 * @author tzp
 * @since 2018/7/9
 */
public class TicketLock21 implements TicketLock {
    private static ConcurrentHashMap<Long, AtomicInteger> ticketLockMap = new ConcurrentHashMap<>();

    @Override
    public Object getLock(Long ticketNumber) {
        ticketLockMap.putIfAbsent(ticketNumber, new AtomicInteger(0));
        AtomicInteger ticketLock = ticketLockMap.get(ticketNumber);
        ticketLock.incrementAndGet();
        return ticketLock;
    }

    @Override
    public void removeLock(Long ticketNumber) {
        AtomicInteger ticketLock = ticketLockMap.get(ticketNumber);
        if (ticketLock != null && ticketLock.decrementAndGet() == 0) {
            ticketLockMap.remove(ticketNumber);
        }
    }
}
